﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MyMario.Helpers;
using System.IO;


namespace MyMario.GameObject
{
    class GameManager
    {
       private Person person;
       int levelLength;
       static int ScrollX;
       float g = 0.2f;
       List<Blocks> blockList;
       List<Money> moneyList;
       List<Monster> monsterList;
       List<InvisibleBlocks> invizList;
       Finish fin;
       public int playersScors;
       public int lives;
       public bool win;
       

        public GameManager()
        {
            Rectangle rect = new Rectangle(66, 500, LoadHelp.Textures[TextureEnum.Person].Width, LoadHelp.Textures[TextureEnum.Person].Height);
            person = new Person(rect, 0.5f, LoadHelp.Textures[TextureEnum.PersonRunleft], LoadHelp.Textures[TextureEnum.PersonRunright], LoadHelp.Textures[TextureEnum.PersonJump]);
            lives = 3;
            win = false;
           
        }

    public  void Respaun()
    {
        if (this.lives < 0)
        {
            this.lives = 3;
            this.CreateLevel();
            this.playersScors = 0;
            this.win = false;
        }
    }

        public bool  MoneyGathering(Rectangle rect)
        {
           
            foreach (Money mon in moneyList)
            {
                if (mon.Rect.Intersects(rect))
                {
                    
                    moneyList.Remove(mon);
                    playersScors += 10;
                    return true;
                }
                             
            }
            return false;  
}

        public bool CollidesWithInvivsibleBlock(Rectangle rect)
        {
            foreach (InvisibleBlocks inviz in invizList)
            {
                if (inviz.Rect.Intersects(rect))
                {
                    invizList.Remove(inviz);
                    return true;
                }
            }
            return false;
        }
        public bool CollidesWithLevel(Rectangle rect)
        {
            foreach (Blocks block in blockList)
            {
                if (block.Rect.Intersects(rect))   
                    return true;
                
            }
            return false;
        }

        public bool KillMonster(Rectangle rect)
        {
            foreach (Monster monster in monsterList)
            {
                if (monster.Rect.Intersects(rect))
                {
                    monsterList.Remove(monster);
                    playersScors += 30;
                    return true;
                }

            }
            return false;
        }

        public bool CollideWithMonster(Rectangle rect)
        {
            foreach (Monster monster in monsterList)
            {
                if (monster.Rect.Intersects(rect))
                {
                    Death();
                    return true;
                }

            }
            return false;
        }

        public bool Finishing(Rectangle rect)
        {
            if (rect.Intersects(fin.Rect))
            {
                this.win = true;
                return true;
            }
            return false;
            
        }

        public static Rectangle GetScreenRect(Rectangle rect)
        {
            Rectangle screenRect = rect;
            screenRect.Offset(-ScrollX, 0);

            return screenRect;
        }

        public void Scroll(int dx)
        {
            if (ScrollX + dx >= 0 && ScrollX + dx <= levelLength - MarioGame.Width)
                ScrollX += dx;
        }

        public void CreateLevel()
        {
            string[] s = File.ReadAllLines("content/Levels/level1.txt");
            blockList = new List<Blocks>();
            moneyList = new List<Money>();
            monsterList = new List<Monster>();
            invizList = new List<InvisibleBlocks>();
            levelLength = 66 * s[0].Length;
            int x = 0;
            int y = 0;
            foreach (string str in s)
            {
                foreach (char c in str)
                {
                    Rectangle rect = new Rectangle(x, y, 66, 66);
                    
                    if (c == 'X')
                    {

                        Blocks  block = new Blocks(rect,1 );
                        blockList.Add(block);
                    }
                    if (c == 'I')
                    {
                        InvisibleBlocks inviz = new InvisibleBlocks(rect,0);
                        invizList.Add(inviz);
                    }

                    if (c == 'N')
                    {
                        InvisibleBlocks inviz = new InvisibleBlocks(rect, 1);
                        invizList.Add(inviz);
                    }
                    if (c == 'Y')
                    {
                        Blocks block = new Blocks(rect, 0);
                        blockList.Add(block);
                    }
                    if (c == 'Z')
                    {
                        Money mon = new Money(rect);
                        moneyList.Add(mon);
                    }

                    if(c=='F')
                         fin = new Finish(rect);

                    if (c == 'W')
                    {
                        
                        Monster monster = new Monster(rect, LoadHelp.Textures[TextureEnum.GhoustLeft]);
                        monsterList.Add(monster);
                    }

                    x += 66;
                }
                x = 0;
                y += 66;
            }
        }

        public float ApplyGravity(GameTime gameTime, Person person)
        {
            person.YVelocity = person.YVelocity - g * gameTime.ElapsedGameTime.Milliseconds / 10;
            float dy = person.YVelocity * gameTime.ElapsedGameTime.Milliseconds / 10;
            
            return -dy;
        }

        public void Update(GameTime gameTime)
        {
            Rectangle nextPosition = person.Rect;
            int dx = 5 * gameTime.ElapsedGameTime.Milliseconds / 10;
            //if (!CollidesWithLevelVertical(person.Rectangle))
            nextPosition.Offset(0, (int)ApplyGravity(gameTime, person));



            
            


            if (nextPosition.Top > 0
              && !CollidesWithLevel(nextPosition) && !MoneyGathering(nextPosition) && !KillMonster(nextPosition)&& !CollidesWithInvivsibleBlock(nextPosition)&&!Finishing(nextPosition))
                person.Rect = nextPosition;
           
            if (!person.OnScreen)
                Death();
            
            bool collideOnFallDown = (CollidesWithLevel(nextPosition) && person.YVelocity < 0);

            if ( collideOnFallDown)
            {
                person.YVelocity = 0;
                person.IsJumping = false;
            }

            foreach (Monster monster in monsterList)
            {
                MoveMonster(dx, 0, monster);
                monster.Update();
            }

            Rectangle heroScreenRect = GetScreenRect(person.Rect);

            if (heroScreenRect.Left < MarioGame.Width / 2)
                Scroll(-7);
            if (heroScreenRect.Right > MarioGame.Width / 2)
                Scroll(7);

            person.Update();



        }

        public void Death()
        {
            Rectangle newPosition = person.Rect;
            newPosition.Location = new Point(66, 500);
            person.Rect = newPosition;
            lives -= 1;
            
                
        }

       private void MoveMonster(int dx, int dy,  Monster monster)
        {

            if (monster.Distance > 300)
                monster.GoRight = false;
            if (monster.Distance < -200)
                monster.GoRight = true;

            if (!monster.GoRight)
                dx = -dx;

            monster.Distance += dx;


            Rectangle nextPosition = monster.Rect;
            nextPosition.Offset(dx, dy);

            if (nextPosition.Intersects(person.Rect))
                Death();
            
            if (!CollidesWithLevel(nextPosition))
                monster.Rect = nextPosition;
            else
                if (monster.GoRight)
                    monster.GoRight = false;
                else
                    monster.GoRight = true;



        }

        public void MovePerson(int dx, int dy, bool runright)
        {
            person.StartRun(runright);
            Rectangle nextPosition = person.Rect;
            nextPosition.Offset(dx, dy);

            

            if (!CollidesWithLevel(nextPosition) && !MoneyGathering(nextPosition) && !CollideWithMonster(nextPosition) && !Finishing(nextPosition))
               person.Rect = nextPosition;
               
            
            
        }

        public void StopPerson()
        {
            person.Stop();
        }
        public void JumpPerson()
        {
           
            
            person.Jump();
           

        }

        #region draw
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Begin();


            if (lives > -1)
            {

                person.Draw(spriteBatch);

                fin.Draw(spriteBatch);

                foreach (Blocks block in blockList)
                {
                    block.Draw(spriteBatch);
                }

                foreach (Money mon in moneyList)
                {
                    mon.Draw(spriteBatch);
                }

                foreach (InvisibleBlocks inviz in invizList)
                {
                    inviz.Draw(spriteBatch);
                }

                foreach (Monster monster in monsterList)
                {
                    monster.Draw(spriteBatch);
                }

                spriteBatch.DrawString(LoadHelp.Fonts[FontEnum.Arial22],
                                        "Score:" + playersScors.ToString(),
                                       new Vector2(0, 0), Color.White);

                spriteBatch.DrawString(LoadHelp.Fonts[FontEnum.Arial22],
                                       "Lives:" + lives.ToString(),
                                      new Vector2(540, 0), Color.White);
            }
            else
            {
                if (!win)
                {
                    spriteBatch.DrawString(LoadHelp.Fonts[FontEnum.Arial42],
                                            "You lose game!",
                                           new Vector2(100, 240), Color.Red);
                    spriteBatch.DrawString(LoadHelp.Fonts[FontEnum.Arial42],
                                            "Your score:" + playersScors.ToString(),
                                           new Vector2(100, 360), Color.White);
                }
                else
                {
                    spriteBatch.DrawString(LoadHelp.Fonts[FontEnum.Arial42],
                                            "Congratulate! You win!",
                                           new Vector2(50, 240), Color.Red);
                    spriteBatch.DrawString(LoadHelp.Fonts[FontEnum.Arial42],
                                        "Your score:" + playersScors.ToString(),
                                       new Vector2(100, 360), Color.White);
                }
            }
            spriteBatch.End();


        }
        #endregion
    }
}

